/**
 * Author: jc
 * Date: 2021-11-18
 * Description: 标注功能
 * FilePath: @/components/hooks/useLabel
 */
import creator from 'wklabel/utils';
import {ref, onMounted, watch} from 'vue';
import {MODE, DOWNLOAD_MODE} from 'wklabel/constants';

// common drawing style
const drawStyle = {
    fillStyle: '#1296db',
    strokeStyle: '#1296db', 
    lineJoin: 'round',
    lineCap: 'round',
    arrow: false,
    globalAlpha: .8,
    lineWidth: 3
};
// polygon style
const polygonStyle = {
    ...drawStyle,
    lineWidth: 3,
    arrow: false,
    globalAlpha: .8,
    fill: true,
    stroke: true
};
// drawer style
const drawerStyle = {
    ...drawStyle,
    lineWidth: 20,
    globalAlpha: .8,
    fill: true,
    stroke: true
};
// text style
const textStyle = {
    ...drawStyle,
    fillStyle: 'red',
    strokeStyle: 'red',
    background: true,
    globalAlpha: .8,
    fontColor: '#FFF'
};

const defaultTitle = '中华人民共和国';

const imageId = 'drawerImageId';

export default props => {
    const mapRef = ref();
    const featureRef = ref();
    const maskRef = ref();
    const imageRef = ref();
    const textRef = ref();
    const titleRef = ref();

    // 绘制结束时触发
    const bindActiveEvent = (map, featureLayer, maskLayer, type, data) => {
        switch(type) {
            // point
            case MODE.POINT:
                const pointFeature = creator.createFeaturePoint({
                    id: `${+new Date()}`,
                    shape: {...data, sr: 3},
                    style: drawStyle
                });
                featureLayer.addFeature(pointFeature);
                break;
            // line
            case MODE.LINE:
                const lineFeature = creator.createFeatureline({
                    id: `${+new Date()}`,
                    shape: {...data, width: map.getScaleSize(3)},
                    style: drawStyle
                });
                featureLayer.addFeature(lineFeature);
                break;
            // rect
            case MODE.RECT:
                const rectFeature = creator.createFeatureRect({
                    id: `${+new Date()}`,
                    shape: data,
                    style: drawStyle
                });
                featureLayer.addFeature(rectFeature);
                break;
            // polyine
            case MODE.POLYLINE:
                const polylineFeature = creator.createFeaturePolyLine({
                    id: `${+new Date()}`,
                    shape: {points: data, width: map.getScaleSize(3)},
                    style: polygonStyle
                });
                featureLayer.addFeature(polylineFeature);
                break;
            // polygon
            case MODE.POLYGON:
                const polygonFeature = creator.createFeaturePolygon({
                    id: `${+new Date()}`,
                    shape: {points: data},
                    style: polygonStyle
                });
                featureLayer.addFeature(polygonFeature);
                break;
            // circle
            case MODE.CIRCLE:
                const circleFeature = creator.createFeatureCircle({
                    id: `${+new Date()}`,
                    shape: data,
                    style: drawStyle
                });
                featureLayer.addFeature(circleFeature);
                break;
            // marker
            case MODE.MARKER:
                const {x, y} = data;
                const marker = creator.createImage({
                    id: `${+new Date()}`,
                    category: '钢笔',
                    shape: {
                        src: './marker.png',
                        width: 30,
                        height: 30,
                        position: {x: x - 15, y: y - 30}
                    }
                });
                maskLayer.addAction(marker);
                break;
            // draw
            case MODE.DRAWMASK:
                const drawMaskAction = creator.createDrawer({
                    id: `${+new Date()}`,
                    shape: {points: data, width: map.getScaleSize(20)},
                    style: drawerStyle
                });
                maskLayer.addAction(drawMaskAction);
                break;
            // clear
            case MODE.CLEARMASK:
                const clearMaskAction = creator.createClear({
                    id: `${+new Date()}`,
                    shape: {points: data, width: map.getScaleSize(20)}
                })
                maskLayer.addAction(clearMaskAction);
                break;
            default:
                break;

        }
    };

    // 创建文本层和初始化文本(2)
    const loadTextLayer = () => {
        const textLayer = creator.createTextLayer();
        const text = creator.createText({
            shape: {text: defaultTitle, position: {x: -195, y: -80}, offset: {x: 0, y: 0}}, // shape
            style: textStyle
        });
        textLayer.addText(text); 
        titleRef.value = text;
        return textLayer;  
    };

    // 创建工具和加载图层(1)
    const loadGLabel = () => {
        // create root instance
        const map = creator.createMap({id: props.value.rootId, options: {
            mode: MODE.PAN,
            withHotKeys: false,
            zoomWhenDrawing: false,
            zoomWheelRatio: 10,
            zoom: 1000,
            size: {
                width: 952,
                height: 567
            },
            position: {
                x: 0,
                y: 0
            },
        }});
        // feature layer
        const featureLayer = creator.createFeatureLayer()
        // drawer layer
        const maskLayer = creator.createMaskLayer({style: {opacity: 1}});
        // text layer
        const textLayer = loadTextLayer();
        // register layers
        map.register(featureLayer)
            .register(maskLayer)
            .register(textLayer);
        map.refresh();
        // 绑定事件
        const events = {
            drawDone: (...events) => bindActiveEvent(map, featureLayer, maskLayer, ...events),
            featureSelected: feature => map.setActiveFeature(feature),
            featureUnselected: () => map.setActiveFeature(null),
            featureUpdated: (feature, shape) => feature.updateShape(shape),
            featureDeleted: ({id: featureId}) => featureLayer.removeFeatureById(featureId), //右击
            click: (...events) => clickInfo(...events), // 单击
        };
        Object.keys(events).forEach(eventName => {
            map.events.on(eventName, events[eventName]);
        });
        // cache instances
        mapRef.value = map;
        featureRef.value = featureLayer;
        maskRef.value = maskLayer;
        textRef.value = textLayer;
    };
    // 单击事件
    const clickInfo = (map, featureLayer, maskLayer, ...events)=>{
       console.log('单击事件', map, featureLayer, maskLayer, ...events)
    }

    // 下载
    const download = () => {
        const map = mapRef.value;
        const image = imageRef.value;
        const {width, height} = image.imageInfo;
        const imageLayer = imageRef.value;
        const featureLayer = featureRef.value;
        const maskLayer = maskRef.value;
        const textLayer = textRef.value;
        map.exportImage({
            type: DOWNLOAD_MODE.BASE64,
            bounds: {x: -210, y: -110, width, height},
            option: {
                layers: [imageLayer, featureLayer, maskLayer, textLayer]
            }
        });
    };

    // 获取所有数据
    const getAllData = () => {
        const featureLayer = featureRef.value;
        const data = featureLayer.getAllFeatures();
        return data;
    };

    // get draw daata获取绘图数据
    const getRle = () => {
        const maskLayer = maskRef.value;
        const rleData = maskLayer.getRleData({x: 0, y: 0, width: 500, height: 354});
        return rleData;
    };

    // 放大
    const zoomIn = () => {
        const map = mapRef.value;
        map.zoomIn();
    };

    // 缩小
    const zoomOut = () => {
        const map = mapRef.value;
        map.zoomOut();
    };

    // 更改文本
    const updateText = text => {
        const titleInstance = titleRef.value;
        titleInstance.updateText(text || ' ');
    };

    // 绘制时设置样式
    const setMode = mode => {
        const map = mapRef.value;
        map.setMode(mode);
        map.setDrawingStyle(drawStyle);
        if (mode === MODE.POLYGON) {
            map.setDrawingStyle(polygonStyle);
        }
        if (mode === MODE.DRAWMASK || mode === MODE.CLEARMASK) {
            map.setDrawingStyle(drawerStyle);
        }
        // ...others
    };

    // 删除功能
    const deleteActiveFeature = () => {
        const map = mapRef.value;
        const activeFeature = map.getActiveFeature();
        if (!activeFeature) {
            return;
        }
        const featureLayer = featureRef.value
        const activeFeatureId = activeFeature.id;
        featureLayer.removeFeatureById(activeFeatureId);
    };

    // clear map 清空地图
    const reset = () => {
        const map = mapRef.value || {};
        const featureLayer = featureRef.value;
        const maskLayer = maskRef.value;
        const markerLayer = map.markerLayer;
        featureLayer && featureLayer.removeAllFeatures();
        maskLayer && maskLayer.removeAllActions();
        markerLayer && markerLayer.removeAllMarkers();
        updateText(defaultTitle);
    };

    // init初始化
    onMounted(() => {
        loadGLabel();
    });

    // watch effect & change background image
    watch([mapRef, props], () => {
        const map = mapRef.value;
        if (!map) {
            return;
        }
        // reset
        map.removeLayerById(imageId);
        reset();
        // create image layer & append layer
        const imageLayer = creator.createImageLayer({id: imageId, options: {
            width: 952,
            height: 567,
            src: props.value.image,
            position: {
                x: -210,
                y: -110
            }
        }});
        map.addLayer(imageLayer);
        imageRef.value = imageLayer;
    });

    return {
        mapRef,
        featureRef,
        maskRef,
        textRef,
        download,
        getAllData,
        getRle,
        reset,
        zoomIn,
        zoomOut,
        updateText,
        setMode,
        deleteActiveFeature
    };
};